package com.canic.dkd.base.aop;

import com.canic.dkd.base.annotations.CreateAt;
import com.canic.dkd.base.annotations.CreateBy;
import com.canic.dkd.base.annotations.UpdateAt;
import com.canic.dkd.base.annotations.UpdateBy;
import com.canic.dkd.base.service.CommonService;
import com.canic.dkd.base.utils.SpringContextUtil;
import lombok.experimental.UtilityClass;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 过滤entity每个字段，把注解 CreateBy CreateAt 过的字段赋值，再进入DAO层
 * @author zc
 */
@UtilityClass
public class AuditingAction {

    public void markCreateAuditing(Object targetEntity) throws IllegalAccessException {
        boolean isList = List.class.isAssignableFrom(targetEntity.getClass());
        if(isList){
            List list = (List) targetEntity;
            if(CollectionUtils.isEmpty(list)){
                return;
            }
            for(Object target : list){
                doMarkCreateAudditingSingle(target);
            }
            return ;
        }
        doMarkCreateAudditingSingle(targetEntity);
    }
    private static void doMarkCreateAudditingSingle(Object targetEntity) throws IllegalAccessException {
        List<Field> fieldList = getFields(targetEntity);
        doMarkCreateAuditing(targetEntity, fieldList);
    }
    private static void doMarkCreateAuditing(Object targetEntity, List<Field> fieldList) throws IllegalAccessException {
        Date currentDate = new Date();
        for (Field field : fieldList) {
            if (AnnotationUtils.getAnnotation(field, CreateBy.class) != null) {
                ReflectionUtils.makeAccessible(field);
                ReflectionUtils.setField(field,targetEntity,getCurrentUser());
            }
            if (AnnotationUtils.getAnnotation(field, CreateAt.class) != null) {
                ReflectionUtils.makeAccessible(field);
                ReflectionUtils.setField(field,targetEntity,currentDate);
            }
        }
    }

    public void markUpdateAuditing(Object targetEntity) throws IllegalAccessException {
        doMarkUpdateAuditingSingle(targetEntity);
    }

    private static void doMarkUpdateAuditingSingle(Object targetEntity) throws IllegalAccessException {
        List<Field> fieldList = getFields(targetEntity);
        Date currentDate = new Date();
        for (Field field : fieldList) {
            if (AnnotationUtils.getAnnotation(field, UpdateBy.class) != null) {
                ReflectionUtils.makeAccessible(field);
                ReflectionUtils.setField(field,targetEntity,getCurrentUser());
            }
            if (AnnotationUtils.getAnnotation(field, UpdateAt.class) != null) {
                ReflectionUtils.makeAccessible(field);
                ReflectionUtils.setField(field,targetEntity,currentDate);
            }
        }
    }
    private static List<Field> getFields(Object targetEntity) {
        List<Field> fieldList = new ArrayList<>();
        Class tempClass = targetEntity.getClass();
        //当父类为null的时候说明到达了最上层的父类(Object类).
        while (tempClass != null) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            //得到父类,然后赋给自己
            tempClass = tempClass.getSuperclass();
        }
        return fieldList;
    }

    /**
     * 获取当前登录人名
     * @return
     */
    private String getCurrentUser(){
        CommonService commonService = (CommonService)SpringContextUtil.getBean("commonService");
        return commonService.getUserName();
    }
}
